use swc_ecma_ast::{ExprStmt, IfStmt};
use swc_ecma_ast::{CallExpr, MemberExpr, MemberProp, OptChainExpr};
use crate::descriptor::FieldDescriptorProto;
use descriptor::field_descriptor_proto::Type as FieldType;
use swc_ecma_ast::*;  // 确保导入必要的AST类型
use heck::{ToLowerCamelCase, ToUpperCamelCase};

use crate::descriptor::EnumDescriptorProto;
use swc_common::DUMMY_SP;
use swc_ecma_ast::{
    AssignOp, AssignTarget, BinaryOp, BindingIdent, BlockStmt, Decl, Expr, KeyValueProp, ObjectLit,
    ParenExpr, Pat, Prop, PropName, PropOrSpread, SimpleAssignTarget, Stmt, SwitchCase, TsAsExpr,
    TsNonNullExpr, VarDecl, VarDeclKind, VarDeclarator, WhileStmt,
};
use swc_ecma_utils::{quote_ident, quote_str};

use crate::{
    context::Context,
    descriptor::{self, OneofDescriptorProto,DescriptorProto},
    runtime::lark::protobuf_js::common::ns_name,
};

use super::{
    codec::{field_accesscor, FieldAccessor},
    common::{normalize_name, normalize_type_name},
    LarkPbRuntime,
};

impl LarkPbRuntime {
    pub(super) fn deserialize_setup_inner(
        &self,
        ctx: &mut Context,
        descriptor: &DescriptorProto,
        ns: &mut Vec<String>,
    ) -> Vec<Stmt> {
        let mut stmts = vec![];
        // const $r = data instanceof $protobuf.Reader ? data : $protobuf.Reader.create(data);
        stmts.push(self.deserialize_setup_reader(ctx));
        // let $m = new XXX();
        stmts.extend(self.deserialize_setup_result(ctx, descriptor, ns));
        // let c = l === undefined ? $r.len : $r.pos + l;
        let stmts_map = Self.deserialize_setup_offset();
        for map_stmt in stmts_map {
            stmts.push(map_stmt);
        }
        //while
        stmts.push(self.deserialize_stmt(
            ctx,
            Expr::Ident(quote_ident!("$m")),
            descriptor,
            field_accesscor,
            &ns,
        ));
        stmts.push(self.deserialize_return_result(ctx, descriptor, ns));

        stmts
    }

    fn deserialize_setup_result(
        &self,
        ctx: &mut Context,
        descriptor: &descriptor::DescriptorProto,
        ns: &[String],
    ) -> Vec<Stmt> {
        let mut decls = vec![];
        for field in &descriptor.field {
            if !field.has_oneof_index() {
                let field_ident = quote_ident!(normalize_name(field.name()));
                let ty = if field.is_message() {//message map
                    field.interface_nullish_type_ann(ctx)
                } else {
                    field.nullish_type_annotation(ctx)
                };
                decls.push(VarDeclarator {
                    span: DUMMY_SP,
                    name: Pat::Ident(BindingIdent {
                        id: field_ident.clone(),
                        type_ann: ty,
                    }),
                    init: if field.is_map(ctx) {
                        // 如果是 map 类型，添加默认空对象 {}
                        Some(Box::new(Expr::Object(ObjectLit {
                            span: DUMMY_SP,
                            props: vec![],
                        })))
                    } else {
                        None  // 其他类型保持无初始化
                    },
                    definite: false,
                })
            }
        }
        for oneof in &descriptor.oneof_decl {
            let oneof_ident = quote_ident!(normalize_name(oneof.name()));
            let mut ns = ns.to_vec();
            ns.push(descriptor.name().to_string());
            let oneof_type = crate::type_ref!(crate::entity_name_ident!(
                ctx.lazy_type_ref(&ns_name(&ns, &oneof.name().to_upper_camel_case()))
            ));
            let ty = crate::type_union!(oneof_type, crate::undefined_type!());
            decls.push(VarDeclarator {
                span: DUMMY_SP,
                name: Pat::Ident(BindingIdent {
                    id: oneof_ident,
                    type_ann: Some(Box::new(ty)),
                }),
                init: None,
                definite: false,
            });
        }
        decls
            .into_iter()
            .map(|decl| {
                Stmt::Decl(Decl::Var(Box::new(VarDecl {
                    span: DUMMY_SP,
                    kind: VarDeclKind::Let,
                    declare: false,
                    decls: vec![decl],
                })))
            })
            .collect()
    }



    fn deserialize_return_result(
        &self,
        ctx: &mut Context,
        descriptor: &descriptor::DescriptorProto,
        ns: &[String],
    ) -> Stmt {
        let mut init_props = vec![];
        for field in &descriptor.field {
            if !field.has_oneof_index() {
                let field_ident = quote_ident!(normalize_name(field.name()));

                let init_value = if field.is_optional() {
                    Expr::Ident(field_ident.clone())
                } else {
                    Expr::TsNonNull(TsNonNullExpr {
                        span: DUMMY_SP,
                        expr: Box::new(Expr::Ident(field_ident.clone())),
                    })
                };
                init_props.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
                    key: PropName::Ident(field_ident.clone()),
                    value: Box::new(init_value),
                }))))
            }
        }
        for oneof in &descriptor.oneof_decl {
            let oneof_ident = quote_ident!(normalize_name(oneof.name()));
            init_props.push(PropOrSpread::Prop(Box::new(Prop::Shorthand(oneof_ident))));
        }
        let init_expr = Expr::Object(ObjectLit {
            span: DUMMY_SP,
            props: init_props,
        });
        crate::return_stmt!(init_expr)
    }

    // pub(super) fn deserialize_setup_reader(&self, ctx: &mut Context) -> Stmt {
    //     //
    //     // ctx.get_import_from(
    //     //     Self::RUNTIME_PACKAGE, 
    //     //     "$protobuf",
    //     // );
    //     // 2. 构建 AST 节点时使用 $protobuf.Reader 格式
    //     let pb_namespace = quote_ident!("$protobuf");
    //     let reader_ident = quote_ident!("Reader");
    //     //
    //     // 3. 构建 $protobuf.Reader 引用
    //     let pb_reader = MemberExpr {
    //         span: DUMMY_SP,
    //         obj: Box::new(Expr::Ident(pb_namespace.clone())),
    //         prop: MemberProp::Ident(reader_ident.clone()),
    //     };
    //     let pb_reader_ident = quote_ident!("$protobuf.Reader");
        
    //     let r = Expr::Ident(quote_ident!("$data"));
        
    //     // 构建 instanceof 检查 (protobuf.Reader 而不是 Reader)
    //     let reader_ty_distinct = crate::bin_expr!(
    //         r.clone(),
    //         Expr::Ident(pb_reader_ident.clone()),
    //         BinaryOp::InstanceOf
    //     );
        
    //     // 构建 protobuf.Reader.create($data) 调用
    //     let create_call = crate::call_expr!(
    //         crate::member_expr!(pb_reader_ident.clone(), "create"),
    //         vec![crate::expr_or_spread!(r.clone())]
    //     );
        
    //     let reader_decl_init = crate::cond_expr!(
    //         reader_ty_distinct,
    //         r.clone(),
    //         create_call
    //     );

    //     // 构建 protobuf.Reader 类型注解
    //     let type_ref = TsType::TsTypeRef(TsTypeRef {
    //         span: DUMMY_SP,
    //         type_name: TsEntityName::TsQualifiedName(Box::new(TsQualifiedName {
    //             left: TsEntityName::Ident(pb_namespace),
    //             right: reader_ident,
    //         })),
    //         type_params: None,
    //     });

    //     Stmt::Decl(Decl::Var(Box::new(VarDecl {
    //         span: DUMMY_SP,
    //         declare: false,
    //         kind: VarDeclKind::Const,
    //         decls: vec![VarDeclarator {
    //             span: DUMMY_SP,
    //             name: Pat::Ident(BindingIdent {
    //                 id: quote_ident!("$r"),
    //                 type_ann: Some(Box::new(TsTypeAnn {
    //                     span: DUMMY_SP,
    //                     type_ann: Box::new(type_ref),
    //                 })),
    //             }),
    //             init: Some(Box::new(reader_decl_init)),
    //             definite: false,
    //         }],
    //     })))
    // }

    pub(super) fn deserialize_setup_reader(&self, ctx: &mut Context) -> Stmt {
        let reader = ctx.get_import_from(Self::RUNTIME_PACKAGE, Self::PB_READER_NAME);
        let call = crate::member_expr!(reader.clone(), "create");
        let r = Expr::Ident(quote_ident!("$data"));
        
        // 1. 创建 instanceof 检查表达式
        let reader_ty_distinct = crate::bin_expr!(
            r.clone(),
            Expr::Ident(reader.clone()),
            swc_ecma_ast::BinaryOp::InstanceOf
        );
    
        // 2. 创建类型断言表达式
        let as_reader_ty = TsType::TsTypeRef(TsTypeRef {
            span: DUMMY_SP,
            type_name: TsEntityName::Ident(quote_ident!("Reader")),
            type_params: None,
        });
    
        // 3. 添加类型断言到两个分支
        let true_branch = Box::new(Expr::TsAs(TsAsExpr {
            span: DUMMY_SP,
            expr: Box::new(r.clone()),
            type_ann: Box::new(as_reader_ty.clone()),
        }));
    
        let false_branch = Box::new(Expr::TsAs(TsAsExpr {
            span: DUMMY_SP,
            expr: Box::new(crate::call_expr!(call, vec![crate::expr_or_spread!(r.clone())])),
            type_ann: Box::new(as_reader_ty),
        }));
    
        // 4. 构建条件表达式
        let reader_decl_init = Expr::Cond(CondExpr {
            span: DUMMY_SP,
            test: Box::new(reader_ty_distinct),
            cons: true_branch,
            alt: false_branch,
        });
    
        // 5. 返回变量声明语句
        Stmt::Decl(Decl::Var(Box::new(VarDecl {
            span: DUMMY_SP,
            declare: false,
            kind: VarDeclKind::Const,
            decls: vec![VarDeclarator {
                span: DUMMY_SP,
                name: Pat::Ident(BindingIdent {
                    id: quote_ident!(DUMMY_SP, "$r"),  // 补充 span
                    type_ann: Some(Box::new(TsTypeAnn {
                        span: DUMMY_SP,
                        type_ann: Box::new(TsType::TsTypeRef(TsTypeRef {
                            span: DUMMY_SP,
                            type_name: TsEntityName::Ident(quote_ident!(DUMMY_SP, "Reader")),  // 补充 span
                            type_params: None,
                        })),
                    })),
                }),
                init: Some(Box::new(reader_decl_init)),
                definite: false,
            }],
        })))
    }

    // pub(super) fn deserialize_setup_reader(&self, ctx: &mut Context) -> Stmt {
    //     let reader = ctx.get_import_from(Self::RUNTIME_PACKAGE, Self::PB_READER_NAME);
    //     let call = crate::member_expr!(reader.clone(), "create");
    //     let r = Expr::Ident(quote_ident!("$data"));
    //     let reader_ty_distinct = crate::bin_expr!(
    //         r.clone(),
    //         Expr::Ident(reader.clone()),
    //         swc_ecma_ast::BinaryOp::InstanceOf
    //     );
    //     let reader_decl_init = crate::cond_expr!(
    //         reader_ty_distinct,
    //         r.clone(),
    //         crate::call_expr!(call, vec![crate::expr_or_spread!(r.clone())])
    //     );
    //     Stmt::Decl(crate::const_decl!("$r", reader_decl_init))
    // }

    fn deserialize_setup_offset(&self) -> Vec<Stmt> {
        let r = Expr::Ident(quote_ident!("$r"));
        let len = Expr::Ident(quote_ident!("$l"));
        
        // 创建pos变量声明
        let pos_decl = Stmt::Decl(Decl::Var(Box::new(VarDecl {
            span: DUMMY_SP,
            declare: false,
            kind: VarDeclKind::Let,
            decls: vec![VarDeclarator {
                span: DUMMY_SP,
                name: Pat::Ident(BindingIdent {
                    id: quote_ident!("pos"),
                    type_ann: Some(Box::new(TsTypeAnn {
                        span: DUMMY_SP,
                        type_ann: Box::new(TsType::TsKeywordType(TsKeywordType {
                            span: DUMMY_SP,
                            kind: TsKeywordTypeKind::TsNumberKeyword,
                        })),
                    })),
                }),
                init: Some(Box::new(Expr::Lit(Lit::Num(Number {
                    span: DUMMY_SP,
                    value: 0.0,
                    raw: None,
                })))),
                definite: false,
            }],
        })));
    
        // 创建if语句，使用更准确的判断条件
        let if_stmt = Stmt::If(IfStmt {
            span: DUMMY_SP,
            test: Box::new(crate::bin_expr!(
                len.clone(),
                Expr::Ident(quote_ident!("undefined")),
                BinaryOp::NotEqEq
            )),
            cons: Box::new(Stmt::Expr(ExprStmt {
                span: DUMMY_SP,
                expr: Box::new(Expr::Assign(AssignExpr {
                    span: DUMMY_SP,
                    left: AssignTarget::Simple(SimpleAssignTarget::Ident(quote_ident!("pos").into())),
                    op: AssignOp::Assign,
                    right: Box::new(crate::bin_expr!(
                        crate::member_expr_bare!(r.clone(), "pos"),
                        len.clone(),
                        BinaryOp::Add
                    )),
                })),
            })),
            alt: None,
        });
    
        // 创建$c常量声明
        let c_decl = Stmt::Decl(Decl::Var(Box::new(VarDecl {
            span: DUMMY_SP,
            declare: false,
            kind: VarDeclKind::Const,
            decls: vec![VarDeclarator {
                span: DUMMY_SP,
                name: Pat::Ident(BindingIdent {
                    id: quote_ident!("$c"),
                    type_ann: Some(Box::new(TsTypeAnn {
                        span: DUMMY_SP,
                        type_ann: Box::new(TsType::TsKeywordType(TsKeywordType {
                            span: DUMMY_SP,
                            kind: TsKeywordTypeKind::TsNumberKeyword,
                        })),
                    })),
                }),
                init: Some(Box::new(crate::cond_expr!(
                    crate::bin_expr!(
                        len.clone(),
                        Expr::Ident(quote_ident!("undefined")),
                        BinaryOp::EqEqEq
                    ),
                    crate::member_expr_bare!(r.clone(), "len"),
                    Expr::Ident(quote_ident!("pos"))
                ))),
                definite: false,
            }],
        })));
    
        // 直接返回语句向量，而不是BlockStmt
        vec![pos_decl, if_stmt, c_decl]
    }

    // fn deserialize_setup_offset(&self) -> Stmt {
    //     let r = Expr::Ident(quote_ident!("$r"));
    //     let len = Expr::Ident(quote_ident!("$l"));
    //     let verify_check = crate::bin_expr!(
    //         len.clone(),
    //         Expr::Ident(quote_ident!("undefined")),
    //         BinaryOp::EqEqEq
    //     );
    //     Stmt::Decl(crate::const_decl!(
    //         "$c",
    //         crate::cond_expr!(
    //             verify_check,
    //             crate::member_expr_bare!(r.clone(), "len"),
    //             crate::bin_expr!(
    //                 crate::member_expr_bare!(r.clone(), "pos"),
    //                 len.clone(),
    //                 BinaryOp::Add
    //             )
    //         )
    //     ))
    // }

    fn deserialize_field_setup_stmts(
        &self,
        ctx: &mut Context,
        host: Expr,
        field: &descriptor::FieldDescriptorProto,
        accessor: FieldAccessor,
        deserialize_stmt: Stmt,
        ns: &[String],
    ) -> Vec<Stmt> {
        let mut stmts = vec![];
        if field.is_map(ctx) {//生成scoresed === null ? (scoresed) = {} : scoresed;
            // let field_access = accessor(host.clone(), field, false);
            // // Create an empty object literal instead of new Map
            // let default_value = Expr::Object(ObjectLit {
            //     span: DUMMY_SP,
            //     props: vec![],
            // });
            
            // stmts.push(crate::expr_stmt!(crate::cond_expr!(
            //     crate::bin_expr!(
            //         field_access.clone(),
            //         Expr::Lit(Lit::Null(Null { span: DUMMY_SP })),
            //         BinaryOp::EqEqEq
            //     ),
            //     crate::assign_expr!(
            //         AssignTarget::Simple(SimpleAssignTarget::Paren(ParenExpr {
            //             span: DUMMY_SP,
            //             expr: Box::new(field_access.clone())
            //         })),
            //         default_value,
            //         AssignOp::Assign
            //     ),
            //     field_access
            // )));
        } else if field.is_repeated() {
            let field_access = accessor(host.clone(), field, false);
            let default_value = field.default_value_expr(ctx, false);
            stmts.push(crate::expr_stmt!(crate::cond_expr!(
                crate::bin_expr!(
                    field_access.clone(),
                    Expr::Ident(quote_ident!("undefined")),
                    BinaryOp::EqEqEq
                ),
                crate::assign_expr!(
                    AssignTarget::Simple(SimpleAssignTarget::Paren(ParenExpr {
                        span: DUMMY_SP,
                        expr: Box::new(field_access.clone())
                    })),
                    default_value,
                    AssignOp::Assign
                ),
                field_access
            )));
            // ?= []
            // let assign_taget = AssignTarget::Simple(SimpleAssignTarget::Paren(ParenExpr {
            //     span: DUMMY_SP,
            //     expr: Box::new(accessor(host.clone(), field, false)),
            // }));
            // stmts.push(crate::expr_stmt!(crate::assign_expr!(
            //     assign_taget,
            //     field.default_value_expr(ctx, false),
            //     AssignOp::NullishAssign
            // )));
        }
        let reader_expr = quote_ident!("$r");
        let end_expr = "$c".to_string();
        let end_ident = quote_ident!(end_expr.as_str());
        if field.is_map(ctx) {
            let descriptor = ctx
                .get_map_type(field.type_name())
                .expect(format!("cannot find map thpe {}", field.type_name()).as_str());
            let key_field = &descriptor.field[0];
            let value_field = &descriptor.field[1];

            stmts.extend(vec![
                Stmt::Decl(crate::let_decl!(
                    end_expr.as_str(),
                    None,
                    crate::bin_expr!(
                        crate::call_expr!(crate::member_expr!(reader_expr.clone(), "uint32_")),
                        crate::member_expr!(reader_expr.clone(), "pos"),
                        BinaryOp::Add
                    )
                )),
                Stmt::Decl(crate::let_decl!(
                    "key",
                    key_field.interface_nullish_type_ann(ctx)
                )),
                Stmt::Decl(crate::let_decl!(
                    "value",
                    value_field.interface_nullish_type_ann(ctx)
                )),
                self.deserialize_stmt(ctx, host.clone(), &descriptor, field_accesscor, ns),
                deserialize_stmt,
            ]);
        } else if field.is_packable() {
            stmts.push(crate::if_stmt!(
                crate::bin_expr!(
                    Expr::Paren(swc_ecma_ast::ParenExpr {
                        span: DUMMY_SP,
                        expr: Box::new(crate::bin_expr!(
                            Expr::Ident(quote_ident!("t")),
                            crate::lit_num!(7).into(),
                            BinaryOp::BitAnd
                        ))
                    }),
                    crate::lit_num!(2).into(),
                    BinaryOp::EqEqEq
                ),
                Stmt::Block(BlockStmt {
                    span: DUMMY_SP,
                    stmts: vec![
                        Stmt::Decl(crate::let_decl!(
                            end_expr.as_str(),
                            None,
                            crate::bin_expr!(
                                crate::call_expr!(crate::member_expr!(
                                    reader_expr.clone(),
                                    "uint32_"
                                )),
                                crate::member_expr!(reader_expr.clone(), "pos"),
                                BinaryOp::Add
                            )
                        )),
                        Stmt::While(WhileStmt {
                            span: DUMMY_SP,
                            test: Box::new(crate::bin_expr!(
                                crate::member_expr!(reader_expr.clone(), "pos"),
                                end_ident.clone().into(),
                                BinaryOp::Lt
                            )),
                            body: Box::new(Stmt::Block(BlockStmt {
                                span: DUMMY_SP,
                                stmts: vec![deserialize_stmt.clone()]
                            }))
                        })
                    ]
                }),
                Stmt::Block(BlockStmt {
                    span: DUMMY_SP,
                    stmts: vec![deserialize_stmt.clone()]
                })
            ));
        } else {
            stmts.push(deserialize_stmt);
        }
        stmts
    }

    fn deserialize_message_field_expr(
        &self,
        ctx: &mut Context,
        _host: Expr,
        field: &descriptor::FieldDescriptorProto,
        _accessor: FieldAccessor,
    ) -> Expr {
        let reader_expr = Expr::Ident(quote_ident!("$r"));
        let decoder_full_name = ctx.lazy_type_ref(field.type_name());
        crate::call_expr!(
            crate::member_expr_bare!(
                crate::member_expr_bare!(
                    crate::member_expr!(decoder_full_name, "$meta"),
                    "decoder"
                ),
                "decode"
            ),
            vec![
                crate::expr_or_spread!(reader_expr.clone()),
                crate::expr_or_spread!(crate::call_expr!(crate::member_expr_bare!(
                    reader_expr.clone(),
                    "uint32_"
                )))
            ]
        )
    }

    fn build_enum_matcher(
        enum_def: &EnumDescriptorProto,
        enum_name: &str,
        target_var: &str,
    ) -> Stmt {
        let mut stmts = Vec::new();
        
        for value in &enum_def.value {
            if let (Some(value_name), Some(number)) = (&value.name, value.number) {
                let value_name_str = value_name.as_str();
                
                // 1. 构建条件表达式: $r.int32() == EnumName.VALUE
                let condition = Expr::Bin(BinExpr {
                    span: DUMMY_SP,
                    left: Box::new(Expr::Call(CallExpr {
                        span: DUMMY_SP,
                        callee: Callee::Expr(Box::new(Expr::Member(MemberExpr {
                            span: DUMMY_SP,
                            obj: Box::new(Expr::Ident(Ident {
                                span: DUMMY_SP,
                                sym: "$r".into(),
                                optional: false,
                            })),
                            prop: MemberProp::Ident(Ident {
                                span: DUMMY_SP,
                                sym: "int32".into(),
                                optional: false,
                            }),
                        }))),
                        args: vec![],
                        type_args: None,
                    })),
                    op: BinaryOp::EqEq,
                    right: Box::new(Expr::Member(MemberExpr {
                        span: DUMMY_SP,
                        obj: Box::new(Expr::Ident(Ident {
                            span: DUMMY_SP,
                            sym: enum_name.into(),
                            optional: false,
                        })),
                        prop: MemberProp::Ident(Ident {
                            span: DUMMY_SP,
                            sym: value_name_str.into(),
                            optional: false,
                        }),
                    })),
                });
    
                // 2. 构建赋值语句: target_var = EnumName.VALUE
                let assignment = Stmt::Expr(ExprStmt {
                    span: DUMMY_SP,
                    expr: Box::new(Expr::Assign(AssignExpr {
                        span: DUMMY_SP,
                        op: AssignOp::Assign,
                        left: AssignTarget::Simple(SimpleAssignTarget::Ident(
                            BindingIdent {
                                id: Ident {
                                    span: DUMMY_SP,
                                    sym: target_var.into(),
                                    optional: false,
                                },
                                type_ann: None,
                            }
                        )),
                        right: Box::new(Expr::Member(MemberExpr {
                            span: DUMMY_SP,
                            obj: Box::new(Expr::Ident(Ident {
                                span: DUMMY_SP,
                                sym: enum_name.into(),
                                optional: false,
                            })),
                            prop: MemberProp::Ident(Ident {
                                span: DUMMY_SP,
                                sym: value_name_str.into(),
                                optional: false,
                            }),
                        })),
                    })),
                });
    
                // 3. 构建完整的if语句
                stmts.push(Stmt::If(IfStmt {
                    span: DUMMY_SP,
                    test: Box::new(condition),
                    cons: Box::new(assignment),
                    alt: None,
                }));
            }
        }
        
        // 4. 包装所有if语句到Block中
        Stmt::Block(BlockStmt {
            span: DUMMY_SP,
            stmts,
        })
    }
    
    fn deserialize_enum_field_expr(
        &self,
        ctx: &mut Context,
        _host: Expr,
        descriptor: &DescriptorProto,
        field: &descriptor::FieldDescriptorProto,
        _accessor: FieldAccessor,
    ) -> Expr {
        let target_var = field.name.as_ref().expect("字段名缺失");
        let mut stmts = Vec::new();
        
        // 1. 创建临时变量 `t = $r.int32()`
        let temp_var_decl = Stmt::Decl(Decl::Var(Box::new(VarDecl {
            span: DUMMY_SP,
            kind: VarDeclKind::Let,
            declare: false,
            decls: vec![VarDeclarator {
                span: DUMMY_SP,
                name: Pat::Ident(BindingIdent {
                    id: Ident::new("t".into(), DUMMY_SP),
                    type_ann: Some(Box::new(TsTypeAnn {
                        span: DUMMY_SP,
                        type_ann: Box::new(TsType::TsKeywordType(TsKeywordType {
                            span: DUMMY_SP,
                            kind: TsKeywordTypeKind::TsNumberKeyword,
                        })),
                    })),
                }),
                init: Some(Box::new(Expr::Call(CallExpr {
                    span: DUMMY_SP,
                    callee: Callee::Expr(Box::new(Expr::Member(MemberExpr {
                        span: DUMMY_SP,
                        obj: Box::new(Expr::Ident(Ident::new("$r".into(), DUMMY_SP))),
                        prop: MemberProp::Ident(Ident::new("int32".into(), DUMMY_SP)),
                    }))),
                    args: vec![],
                    type_args: None,
                }))),
                definite: false,
            }],
        })));
    
        stmts.push(temp_var_decl);
    
        // 2. 遍历枚举值，生成条件判断
        for enum_def in &descriptor.enum_type {
            if let Some(enum_name) = &enum_def.name {
                for value in &enum_def.value {
                    if let (Some(value_name), Some(_)) = (&value.name, value.number) {
                        let condition = Box::new(Expr::Bin(BinExpr {
                            span: DUMMY_SP,
                            left: Box::new(Expr::Ident(Ident::new("t".into(), DUMMY_SP))),
                            op: BinaryOp::EqEq,
                            right: Box::new(Expr::Member(MemberExpr {
                                span: DUMMY_SP,
                                obj: Box::new(Expr::Ident(Ident::new(enum_name.as_str().into(), DUMMY_SP))),
                                prop: MemberProp::Ident(Ident::new(value_name.as_str().into(), DUMMY_SP)),
                            })),
                        }));
    
                        let assign_expr = Expr::Assign(AssignExpr {
                            span: DUMMY_SP,
                            op: AssignOp::Assign,
                            left: AssignTarget::Simple(SimpleAssignTarget::Ident(
                                BindingIdent {
                                    id: Ident::new(target_var.as_str().into(), DUMMY_SP),
                                    type_ann: None,
                                }
                            )),
                            right: Box::new(Expr::Member(MemberExpr {
                                span: DUMMY_SP,
                                obj: Box::new(Expr::Ident(Ident::new(enum_name.as_str().into(), DUMMY_SP))),
                                prop: MemberProp::Ident(Ident::new(value_name.as_str().into(), DUMMY_SP)),
                            })),
                        });
    
                        let cond_expr = Expr::Cond(CondExpr {
                            span: DUMMY_SP,
                            test: condition,
                            cons: Box::new(assign_expr),
                            alt: Box::new(Expr::Ident(Ident::new("undefined".into(), DUMMY_SP))),
                        });
    
                        stmts.push(Stmt::Expr(ExprStmt {
                            span: DUMMY_SP,
                            expr: Box::new(cond_expr),
                        }));
                    }
                }
            }
        }
    
        // 3. 构建最终表达式
        if stmts.is_empty() {
            Expr::Ident(Ident::new("undefined".into(), DUMMY_SP))
        } else {
            // 由于 `Expr` 没有 `Block`，改用 `Expr::Seq`（但 `let` 声明不能放在 `SeqExpr` 里）
            // 所以更推荐使用 `Expr::Call`（IIFE 模式）来包含 `let` 声明
            Expr::Call(CallExpr {
                span: DUMMY_SP,
                callee: Callee::Expr(Box::new(Expr::Arrow(ArrowExpr {
                    span: DUMMY_SP,
                    params: vec![],
                    body: Box::new(BlockStmtOrExpr::BlockStmt(BlockStmt {
                        span: DUMMY_SP,
                        stmts,
                    })),
                    is_async: false,
                    is_generator: false,
                    type_params: None,
                    return_type: None,
                }))),
                args: vec![],
                type_args: None,
            })
        }
    }

    fn deserialize_primitive_field_expr(
        &self,
        _ctx: &mut Context, // ctx 在此特定逻辑中不再需要，标记为 _ctx
        _host: Expr,
        field: &descriptor::FieldDescriptorProto,
        _force_unpacked: bool,
    ) -> Expr {
        let field_expr = crate::call_expr!(crate::member_expr!("$r", self.codec_fn_name(field)));
        if field.is_bigint() {
            // 直接使用 field_expr，protobuf.js 的 reader 方法在配置为 bigint:true 时应返回 bigint
            field_expr
        } else {
            // 对于非 bigint 类型，field_expr 也是正确的表达式
            field_expr
        }
        // 注意：上面的 if/else 结构两边都返回 field_expr，
        // 这等价于直接返回 field_expr。
        // 为了与您提供的“修改后”示例的结构保持一致，这里保留了 if/else。
        // 如果追求简洁，可以直接写成:
        // field_expr
    }

    fn deserialize_map_field_expr(
        &self,
        _ctx: &Context,
        host: Expr,
        field: &descriptor::FieldDescriptorProto,
        accessor: FieldAccessor,
    ) -> Expr {
        // Create two separate accessor expressions since we need to use it twice
        let scores_expr1 = accessor(host.clone(), field, false);
        let scores_expr2 = accessor(host, field, false);
    
        // Create the member expression for scores[key]
        let member_expr = MemberExpr {
            span: DUMMY_SP,
            obj: Box::new(scores_expr1),
            prop: MemberProp::Computed(ComputedPropName {
                span: DUMMY_SP,
                expr: Box::new(Expr::Ident(quote_ident!("key"))),
            }),
        };
    
        // Create the assignment expression: scores[key] = value
        let assign_expr = Expr::Assign(AssignExpr {
            span: DUMMY_SP,
            left: AssignTarget::Simple(SimpleAssignTarget::Member(member_expr)),
            op: AssignOp::Assign,
            right: Box::new(Expr::Ident(quote_ident!("value"))),
        });
    
        // Create the inner conditional: scores ? scores[key] = value : undefined
        let inner_cond = Expr::Cond(CondExpr {
            span: DUMMY_SP,
            test: Box::new(scores_expr2),
            cons: Box::new(assign_expr),
            alt: Box::new(Expr::Ident(quote_ident!("undefined"))),
        });
    
        // Create the outer condition: value && key
        let condition = Expr::Bin(BinExpr {
            span: DUMMY_SP,
            left: Box::new(Expr::Ident(quote_ident!("value"))),
            op: BinaryOp::LogicalAnd,
            right: Box::new(Expr::Ident(quote_ident!("key"))),
        });
    
        // Combine everything into the final expression
        Expr::Cond(CondExpr {
            span: DUMMY_SP,
            test: Box::new(condition),
            cons: Box::new(inner_cond),
            alt: Box::new(Expr::Ident(quote_ident!("undefined"))),
        })
    }

    fn deserialize_field_expr(
        &self,
        ctx: &mut Context,
        host: Expr,
        field: &descriptor::FieldDescriptorProto,
        accessor: FieldAccessor,
        force_unpacked: bool,
    ) -> Expr {
        if field.is_map(ctx) {
            self.deserialize_map_field_expr(ctx, host, field, accessor)
        } else if field.is_message() {
            self.deserialize_message_field_expr(ctx, host, field, accessor)
        } else {
            self.deserialize_primitive_field_expr(ctx, host, field, force_unpacked)
        }
    }

    pub fn capitalize(s: &str) -> String {
        let mut chars = s.chars();
        match chars.next() {
            None => String::new(),
            Some(c) => c.to_uppercase().chain(chars).collect(),
        }
    }

    fn deserialize_oneof_field_expr(
        &self,
        ctx: &Context,
        descriptor: &descriptor::DescriptorProto,
        field: &descriptor::FieldDescriptorProto,
        field_expr: &Expr,
        ns: &[String],
    ) -> Expr {
        let oneof: &OneofDescriptorProto = &descriptor.oneof_decl[field.oneof_index() as usize];
        let mut ns = ns.to_vec();
        ns.push(descriptor.name().to_string());
        let oneof_type = crate::type_ref!(crate::entity_name_ident!(ctx.lazy_type_ref(&ns_name(
            &ns,
            &format!(
                "${}_{}",
                normalize_type_name(oneof.name()),
                normalize_type_name(&format!("I{}", LarkPbRuntime::capitalize(field.name())))
            )
        ))));
        Expr::TsAs(TsAsExpr {
            span: DUMMY_SP,
            expr: Box::new(Expr::Object(swc_ecma_ast::ObjectLit {
                span: DUMMY_SP,
                props: vec![
                    PropOrSpread::Prop(Box::new(Prop::KeyValue(swc_ecma_ast::KeyValueProp {
                        key: PropName::Ident(quote_ident!("$oneofKind")),
                        value: Box::new(Expr::Lit(crate::lit_str!(normalize_name(field.name())))),
                    }))),
                    PropOrSpread::Prop(Box::new(Prop::KeyValue(swc_ecma_ast::KeyValueProp {
                        key: PropName::Ident(quote_ident!(normalize_name(field.name()))),
                        value: Box::new(field_expr.clone()),
                    }))),
                ],
            })),
            type_ann: Box::new(oneof_type),
        })
    }

    pub fn deserialize_stmt(
        &self,
        ctx: &mut Context,
        host: Expr,
        descriptor: &DescriptorProto,
        accessor: FieldAccessor,
        ns: &[String],
    ) -> Stmt {
        let mut cases: Vec<SwitchCase> = vec![];
        let reader_expr = Expr::Ident(quote_ident!("$r"));
        for field in &descriptor.field {
            let field_expr = self.deserialize_field_expr(ctx, host.clone(), field, accessor, false);
            let field_expr = if field.has_oneof_index() {
                self.deserialize_oneof_field_expr(ctx, descriptor, field, &field_expr, ns)
            } else {
                field_expr
            };
            let read_expr = if field.has_oneof_index() {
                let oneof = &descriptor.oneof_decl[field.oneof_index() as usize];
                crate::assign_expr!(
                    AssignTarget::Simple(SimpleAssignTarget::Ident(BindingIdent {
                        id: quote_ident!(normalize_name(oneof.name())),
                        type_ann: None
                    })),
                    field_expr
                )
            } else if field.is_enum(){
                self.deserialize_enum_field_expr(ctx, host.clone(), descriptor, field, accessor)
            } else if field.is_map(ctx) {
                field_expr
            } else if field.is_repeated() && !field.is_packed(ctx) {
                Expr::Cond(CondExpr {
                    span: DUMMY_SP,
                    test: Box::new(accessor(host.clone(), field, false)),
                    cons: Box::new(crate::call_expr!(
                        crate::member_expr_bare!(accessor(host.clone(), field, false), "push"),
                        vec![crate::expr_or_spread!(field_expr)]
                    )),
                    alt: Box::new(Expr::Ident(quote_ident!("undefined"))),
                })
                // crate::call_expr!(
                //     crate::member_expr_bare!(accessor(host.clone(), field, false), "push"),
                //     vec![crate::expr_or_spread!(field_expr)]
                // )
            } else {
                crate::assign_expr!(
                    AssignTarget::Simple(SimpleAssignTarget::Paren(ParenExpr {
                        span: DUMMY_SP,
                        expr: Box::new(accessor(host.clone(), field, false))
                    })),
                    field_expr
                )
            };
            //生成case中的内容
            let stmts = self.deserialize_field_setup_stmts(
                ctx,
                host.clone(),
                field,
                accessor,
                crate::expr_stmt!(read_expr),
                ns,
            );
            // 为所有语句添加类型注解
            let stmts = self.add_type_annotations_to_stmts(stmts, Some(field));
            let mut stmts = if stmts.len() > 1 {
                vec![Stmt::Block(BlockStmt {
                    span: DUMMY_SP,
                    stmts,
                })]
            } else {
                stmts
            };
            stmts.push(Stmt::Break(swc_ecma_ast::BreakStmt {
                span: DUMMY_SP,
                label: None,
            }));

            cases.push(SwitchCase {
                span: DUMMY_SP,
                test: Some(Box::new(crate::lit_num!(field.number()).into())),
                cons: stmts,
            });
        }

        cases.push(SwitchCase {
            span: DUMMY_SP,
            test: None,
            cons: vec![
                crate::expr_stmt!(crate::call_expr!(
                    crate::member_expr_bare!(reader_expr.clone(), "skipType_"),
                    vec![crate::expr_or_spread!(crate::bin_expr!(
                        Expr::Ident(quote_ident!("t")),
                        crate::lit_num!(7).into(),
                        BinaryOp::BitAnd
                    )),]
                )),
                Stmt::Break(swc_ecma_ast::BreakStmt {
                    span: DUMMY_SP,
                    label: None,
                }),
            ],
        });

        let pos_expr = crate::member_expr_bare!(reader_expr.clone(), "pos");
        let while_test_expr =
            crate::bin_expr!(pos_expr, Expr::Ident(quote_ident!("$c")), BinaryOp::Lt);

        Stmt::While(WhileStmt {
            span: DUMMY_SP,
            test: Box::new(while_test_expr),
            body: Box::new(Stmt::Block(BlockStmt {
                span: DUMMY_SP,
                stmts: vec![
                    Stmt::Decl(Decl::Var(Box::new(VarDecl {
                        span: DUMMY_SP,
                        kind: VarDeclKind::Let,
                        declare: false,
                        decls: vec![VarDeclarator {
                            span: DUMMY_SP,
                            name: swc_ecma_ast::Pat::Ident(BindingIdent {
                                id: quote_ident!("t"),
                                type_ann: Some(Box::new(TsTypeAnn {
                                    span: DUMMY_SP,
                                    type_ann: Box::new(TsType::TsKeywordType(TsKeywordType {
                                        span: DUMMY_SP,
                                        kind: TsKeywordTypeKind::TsNumberKeyword,
                                    })),
                                })),
                            }),
                            init: Some(Box::new(crate::call_expr!(crate::member_expr_bare!(
                                reader_expr.clone(),
                                "uint32_"
                            )))),
                            definite: false,
                        }],
                    }))),
                    Stmt::Switch(swc_ecma_ast::SwitchStmt {
                        span: DUMMY_SP,
                        discriminant: Box::new(crate::bin_expr!(
                            Expr::Ident(quote_ident!("t")),
                            crate::lit_num!(3).into(),
                            BinaryOp::ZeroFillRShift
                        )),
                        cases,
                    }),
                ],
            })),
        })
    }

   // 新增方法：递归添加类型注解
   pub fn add_type_annotations_to_stmts(
        &self,
        stmts: Vec<Stmt>,
        field: Option<&FieldDescriptorProto>,
    ) -> Vec<Stmt> {
        stmts
            .into_iter()
            .map(|stmt| self.add_type_annotations_to_stmt(stmt, field))
            .collect()
    }

    /// 处理单个语句
    fn add_type_annotations_to_stmt(
        &self,
        stmt: Stmt,
        field: Option<&FieldDescriptorProto>,
    ) -> Stmt {
        match stmt {
            // 处理变量声明（只处理带初始值的 let）
            Stmt::Decl(Decl::Var(var_decl)) => Stmt::Decl(Decl::Var(Box::new(VarDecl {
                decls: self.process_var_declarators(var_decl.decls, field),
                ..*var_decl
            }))),

            // 递归处理块语句
            Stmt::Block(block) => Stmt::Block(BlockStmt {
                stmts: self.add_type_annotations_to_stmts(block.stmts, field),
                ..block
            }),

            // 递归处理 if 语句
            Stmt::If(if_stmt) => Stmt::If(IfStmt {
                cons: Box::new(self.add_type_annotations_to_stmt(*if_stmt.cons, field)),
                alt: if_stmt.alt.map(|a| Box::new(self.add_type_annotations_to_stmt(*a, field))),
                ..if_stmt
            }),

            // 其他语句保持不变
            other => other,
        }
    }

    /// 处理变量声明列表
    fn process_var_declarators(
        &self,
        decls: Vec<VarDeclarator>,
        field: Option<&FieldDescriptorProto>,
    ) -> Vec<VarDeclarator> {
        decls
            .into_iter()
            .map(|decl| {
                // 只处理带初始值的声明
                if let Some(init) = decl.init {
                    VarDeclarator {
                        name: self.add_type_to_binding(decl.name, &init, field),
                        init: Some(init),
                        ..decl
                    }
                } else {
                    // 无初始值的声明原样保留
                    decl
                }
            })
            .collect()
    }

    /// 为绑定添加类型注解
    fn add_type_to_binding(
        &self,
        pat: Pat,
        init_expr: &Expr,
        field: Option<&FieldDescriptorProto>,
    ) -> Pat {
        match pat {
            Pat::Ident(binding) => Pat::Ident(BindingIdent {
                
                type_ann: Some(Box::new(TsTypeAnn {
                    span: DUMMY_SP,
                    type_ann: Box::new(self.infer_type(init_expr,binding.id.sym.as_ref(), field)),
                })),
                ..binding
            }),
            // 解构赋值不处理（保持原样）
            other => other,
        }
    }

    /// 统一类型推断（优先使用 protobuf 字段类型）
    fn infer_type(&self, expr: &Expr, var_name: &str, field: Option<&FieldDescriptorProto>) -> TsType {
        field.map_or_else(
            || self.infer_type_from_expr(expr), // 无字段信息时从表达式推断
            |f| self.infer_var_type(f, var_name ,Some(expr)),// 有字段信息时使用 protobuf 类型
        )
    }

    /// 从 protobuf 字段推断类型
    fn infer_var_type(&self, field: &FieldDescriptorProto, var_name: &str, expr: Option<&Expr>) -> TsType {
        // 优先识别特殊变量名
        match var_name {
            // 位置相关变量都是 number 类型
            "$c" | "$pos" | "$end" | "$r" => return TsType::TsKeywordType(TsKeywordType {
                span: DUMMY_SP,
                kind: TsKeywordTypeKind::TsNumberKeyword,
            }),
            _ => {}
        }

        // 其次检查表达式类型
        if let Some(expr) = expr {
            if let Expr::Bin(bin) = expr {
                if matches!(bin.op, BinaryOp::Add | BinaryOp::Sub) {
                    return TsType::TsKeywordType(TsKeywordType {
                        span: DUMMY_SP,
                        kind: TsKeywordTypeKind::TsNumberKeyword,
                    });
                }
            }
        }
        // 最后回退到字段类型推断
        match field.type_() {
            FieldType::TYPE_STRING => TsType::TsKeywordType(TsKeywordType {
                span: DUMMY_SP,
                kind: TsKeywordTypeKind::TsStringKeyword,
            }),
            FieldType::TYPE_INT32 => TsType::TsKeywordType(TsKeywordType {
                span: DUMMY_SP,
                kind: TsKeywordTypeKind::TsNumberKeyword,
            }),
            FieldType::TYPE_MESSAGE => TsType::TsTypeRef(TsTypeRef {
                span: DUMMY_SP,
                type_name: TsEntityName::Ident(quote_ident!(field.type_name())),
                type_params: None,
            }),
            _ => TsType::TsKeywordType(TsKeywordType {
                span: DUMMY_SP,
                kind: TsKeywordTypeKind::TsAnyKeyword,
            }),
        }
    }

    /// 从表达式推断类型（基础实现）
    fn infer_type_from_expr(&self, expr: &Expr) -> TsType {
        match expr {
            Expr::Lit(lit) => match lit {
                Lit::Num(_) => TsType::TsKeywordType(TsKeywordType {
                    span: DUMMY_SP,
                    kind: TsKeywordTypeKind::TsNumberKeyword,
                }),
                Lit::Str(_) => TsType::TsKeywordType(TsKeywordType {
                    span: DUMMY_SP,
                    kind: TsKeywordTypeKind::TsStringKeyword,
                }),
                Lit::Bool(_) => TsType::TsKeywordType(TsKeywordType {
                    span: DUMMY_SP,
                    kind: TsKeywordTypeKind::TsBooleanKeyword,
                }),
                _ => TsType::TsKeywordType(TsKeywordType {
                    span: DUMMY_SP,
                    kind: TsKeywordTypeKind::TsAnyKeyword,
                }),
            },
            _ => TsType::TsKeywordType(TsKeywordType {
                span: DUMMY_SP,
                kind: TsKeywordTypeKind::TsAnyKeyword,
            }),
        }
    }
}
